Django建站历程:(十三)基于django-haystack的全文搜索

2018年12月31日 Jerry 5857 2021年1月17日

       本文记录django最常用的搜索方法,基于django-haystack框架、whoosh引擎、jieba分词的搜索模块实现。

1、安装所需组件:

root@jerryls-site1:/home# pip install whoosh #全文搜索引擎
root@jerryls-site1:/home# pip install django-haystack #搜索框架
root@jerryls-site1:/home# pip install jieba  # 中文分词组件

2、添加APP,配置全局settings.py

# Application definition

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',

    # for allauth
    'django.contrib.sites',
    'allauth',
    'allauth.account',
    'allauth.socialaccount',
    'allauth.socialaccount.providers.baidu',

    # for crispy
    'crispy_forms',
    # for blog
    'blog',
    # for myauth
    'myauth',
    # for image
    'imagekit',
    # for ckeditor
    'ckeditor',
    'ckeditor_uploader',
    # for comment
    'comment',
    # for haytack
    'haystack',
]

HAYSTACK_CONNECTIONS = {
    'default':{
        # 'ENGINE': 'haystack.backends.whoosh_backend.WhooshEngine',
        'ENGINE':'blog.whoosh_cn_backend.WhooshEngine',
        'PATH': os.path.join(BASE_DIR, 'whoosh_index'),
    },
}

# 实时自动更新索引配置
HAYSTACK_SIGNAL_PROCESSOR = 'haystack.signals.RealtimeSignalProcessor'

      这里blog下面还没有“whoosh_cn_backend”这个文件,需要下面步骤进行添加:

      拷贝“whoosh_backend.py”(/usr/local/lib/python3.5/dist-packages/haystack/backends/whoosh_backend.py)文件到blog下,并重命名为whoosh_cn_backend.py,

     修改代码如下:

from jieba.analyse import ChineseAnalyzer   #手动添加结巴分词

# 找到下面这句,大约在160行左右,修改如下:
# schema_fields[field_class.index_fieldname] = TEXT(stored=True, analyzer=StemmingAnalyzer(), field_boost=field_class.boost, sortable=True) 

schema_fields[field_class.index_fieldname] = TEXT(stored=True, analyzer=ChineseAnalyzer(), field_boost=field_class.boost, sortable=True)

3、创建索引文件

       我们对文章这个model进行搜索,进入到blog文件夹创建索引:需要创建一个名字固定为“search_indexes.py”的文件,修改代码如下:

# -*- coding: utf-8 -*-

from haystack import indexes
from .models import Article


class ArticleIndex(indexes.SearchIndex, indexes.Indexable): # 名字必须是model名+Index
    text = indexes.CharField(document=True, use_template=True)

    def get_model(self):
        return Article

    def index_queryset(self, using=None):
        return self.get_model().objects.all()

       在全局模板文件夹下创建templates/search/indexes/blog文件夹及article_text.txt文件,注意这里的article_text.txt文件名字是“model名_text.txt”,用别的名字会报错。同时创建一个搜索模板文件search.html显示结果用:

root@jerryls-site1:/home/mysite/templates# tree
├── account
│   
.....
.....

├── search
│      └── indexes
│             └── blog
│                   └── article_text.txt
└── search.html
# article_text.txt

{{ object.title }}
{{ object.summary }}
{{ object.body }}

       这里指定了对文章的title、summary、body进行搜索。

       以下为search.html文件代码:其中{{query}}就是输入的关键字,“{% for result in page.object_list %}”可以遍历结果列表,result.object 即 article。“highlight”对结果进行高亮显示

{% extends "blog/base.html" %}
{% load highlight %}

{% block base_content %}

<style>
span.highlighted { color: red; }

.col-center-block {
        float: none;
        display: block;
        margin: 0 auto;
        /* margin-left: auto; margin-right: auto; */
}
</style>

<div class="container">
    <div class="row">
        <div class="text-center">

          <div class="list-group col-lg-8 col-center-block">
             <a class="list-group-item disabled">当前搜索:{{ query }}</a>
{% for result in page.object_list %}

             <div class="list-group-item">
                <a href="{% url 'blog:article_url' result.object.slug %}">{{result.object.title}}</a>
                <br>
{% with result.object.body|safe as body %}
                <span>{% highlight body with query %}</span>
{% endwith %}
             </div>
{% empty %}
             <h3>未搜索到相关内容!</h3>
{% endfor %}
         </div>
    </div>
</div>

{% endblock %}

4、配置搜索路由

       在blog中添加搜索路由:

urlpatterns = [
    path('', index_view, name='index_url'),
    path('article/<str:slug>', article_view, name='article_url'),
    path('cata/<str:slug>', catalogue_view, name='cata_url'),
    path('search/', include('haystack.urls')),    # 搜索路由
]

5、修改导航栏、搜索模板文件

     修改nav.html文件,将搜索路由添加到搜索按钮:

<form class="navbar-form navbar-left" method="get" action="{% url 'blog:haystack_search' %}">
   <div class="form-group">
      <input type="text" class="form-control" name="q" placeholder="搜索" required=True>
   </div>
      <button type="submit" class="btn btn-default">搜索</button>
</form>

        需要注意的是,这里的搜索输入框一定要指定个name,内容是“q”,这样才能获得正确的路径给haystack,才能搜索到结果。

6、建立索引

        最后一步,输入以下命令建立索引即可:

root@jerryls-site1:/home/mysite# ./manage.py rebuild_index

最终的实现效果如下:

      天气太冷了,空调死命吹也不好使,躺在被窝也冻得不行。今天是2018年的最后一天,新的一年希望自己可以继续加油、多学习、多进步!提前来个元旦快乐~!


《django 建站历程系列文章》

(一)服务器的选取与环境准备

(二)创建第一个project和app

(三)创建并显示博客的主页导航栏

(四)django-allauth实现用户登陆

(五)django-allauth实现第三方登陆

(六)使用bootstrap3美化登陆界面

(七)添加用户签名字段

(八)自定义用户头像

(九)发布我的第一篇博客

(十)CKEditor的配置使用

(十一)ajax实现文章添加评论

(十二)signal自动消息通知

(十三)基于django-haystack的全文搜索

(十四)配置SSL证书实现网站HTTPS访问

(十五)免费开启七牛云CDN加速

(十六)particles 粒子背景插件

(十七)集成 xadmin2 后台管理

(十八)RestFramework 编写API

(十九)Nginx+uwsgi 部署 django

(二十)自定义网站404界面

(二一)jwt为API添加身份认证

jerrycoding 博客源码大公开


原创文章,转载请注明出处: https://jerrycoding.com/article/site_building_13

微信
jerry微信赞助
支付宝
jerry支付宝赞助

您尚未登录,暂时无法评论。请先 登录 或者 注册

0 人参与 | 0 条评论